module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 

    //rename/define parameters in the case 
    reg [3:0]state, next_state;
    reg [3:0] uns1, s2s1norm, s3s2norm, aboves3, s3s2supp, s2s1supp;
    //assign state values to each state name
    			//fr3 fr2 fr1 dfr
    assign uns1 = {1'b1,1'b1,1'b1,1'b1};
    assign s2s1norm = {1'b0,1'b1,1'b1,1'b0};
    assign s3s2norm = {1'b0,1'b0,1'b1,1'b0};
    assign aboves3 = {1'b0,1'b0,1'b0,1'b0};
    assign s3s2supp = {1'b0,1'b0,1'b1,1'b1};
    assign s2s1supp = {1'b0,1'b1,1'b1,1'b1};

    //fsm transition logic 
    always@(*)begin 
        case(state)
            uns1: 
            if(s[1]&!s[2]&!s[3])begin 
                	next_state = s2s1norm;
            end               				
            	  else next_state = uns1; 
            s2s1norm: 
            if(s[1]&s[2]&!s[3])begin 
                		next_state = s3s2norm;end
            else if(s[1]&!s[2]&!s[3])begin 
                next_state = s2s1norm; end
            else next_state = uns1;
            s3s2norm: 
                if(s[1]&s[2]&s[3])begin 
                    next_state = aboves3;end
            else if(s[1]&!s[2]&!s[3])begin 
                next_state = s2s1supp;end
            else next_state = s3s2norm; 
            aboves3:
                if(s[1]&s[2]&!s[3])begin 
                    next_state = s3s2supp;end
            else next_state = aboves3; 
            s3s2supp: 
                if(s[1]&s[2]&s[3])begin 
                    next_state = aboves3; end
            else if(s[1]&!s[2]&!s[3])begin
                next_state = s2s1supp; end
            else next_state = s3s2supp; 
            s2s1supp: 
                if(s[1]&s[2]&!s[3])begin 
                    next_state = s3s2norm;end
            else if(!s[1]&!s[2]&!s[3])begin 
                next_state = uns1;end
            else next_state = s2s1supp; 
        endcase
    end

    //synchronous logic 
    always@(posedge clk)begin 
        if(reset) 
            begin 
            state <= uns1; 
            end
        else 
            begin 
                state <= next_state;
            end
         end
    
    assign {fr3,fr2,fr1,dfr} = state;

    /*
    // Give state names and assignments. I'm lazy, so I like to use decimal numbers.
	// It doesn't really matter what assignment is used, as long as they're unique.
	// We have 6 states here.
	parameter A2=0, B1=1, B2=2, C1=3, C2=4, D1=5;
	reg [2:0] state, next;		// Make sure these are big enough to hold the state encodings.
    
    // Edge-triggered always block (DFFs) for state flip-flops. Synchronous reset.	
	always @(posedge clk) begin
		if (reset) state <= A2;
		else state <= next;
	end
    
    // Combinational always block for state transition logic. Given the current state and inputs,
    // what should be next state be?
    // Combinational always block: Use blocking assignments.    
	always@(*) begin
		case (state)
			A2: next = s[1] ? B1 : A2;
			B1: next = s[2] ? C1 : (s[1] ? B1 : A2);
			B2: next = s[2] ? C1 : (s[1] ? B2 : A2);
			C1: next = s[3] ? D1 : (s[2] ? C1 : B2);
			C2: next = s[3] ? D1 : (s[2] ? C2 : B2);
			D1: next = s[3] ? D1 : C2;
			default: next = 'x;
		endcase
	end
    
	// Combinational output logic. In this problem, a procedural block (combinational always block) 
	// is more convenient. Be careful not to create a latch.
	always@(*) begin
		case (state)
			A2: {fr3, fr2, fr1, dfr} = 4'b1111;
			B1: {fr3, fr2, fr1, dfr} = 4'b0110;
			B2: {fr3, fr2, fr1, dfr} = 4'b0111;
			C1: {fr3, fr2, fr1, dfr} = 4'b0010;
			C2: {fr3, fr2, fr1, dfr} = 4'b0011;
			D1: {fr3, fr2, fr1, dfr} = 4'b0000;
			default: {fr3, fr2, fr1, dfr} = 'x;
		endcase
	end
    */

endmodule
